'''函数变量'''
# 默认情况下，一个函数会绑定在一个变量上，这个变量就是函数的名字
# 函数作为变量时，可以作为函数的返回值

'''匿名函数'''
# lambda 形参：函数体 !:lambda没有特殊函数，只作为一个标记，表示此处是匿名函数
#                     冒号前面表示这个函数的形参，冒号后面表示函数体，而且不用写return
# 作用：不用起名字，直接定义这个函数的地方使用，语法结构简单，可以实现简单的逻辑


# cards = [{"name":"zhangsan","age":32},
#          {"name":"lisi","age":23},
#          {"name":"wangwu","age":42},]
# # key表示sort函数进行比较的依据
# cards.sort(key=lambda x:x["age"])#冒号前面的x是列表 `cards` 中的每一个元素；冒号后面的x是表示从字典`x`中取出键为"age"的值
# print(cards)

# s = "zxcvb\nnmasdfg\t"
# L = s.split()#以空格，换行tab分割列表
# print(L)#['zxcvb', 'nmasdfg']
# s = " ".join(L)#用单个空格连接列表元素
# print(s)#zxcvb nmasdfg
# f = lambda x:" ".join(x.split())
# print(f(s))#zxcvb nmasdfg


# list(map(lambda x:x**2,range(1,101))) #返回100以内所有的数值的平方组成的列表

# def fn(a,b,func):
#     return func(a,b)
# print(fn(1,2,lambda x,y:x+y))#3


'''eval(source,globals=None,locals=None)'''
# source:必选参数，可以是字符串也可以是对象形式，如果是字符串，会被当作表达式来执行，会使用global全局命名空间和locals给定的变量
# global：以字典的形式提供
# locals：可以是字典也可以是映射对象


'''exec（）'''
#把一个字符串作为程序来执行
# x=1
# y=2
# s = "print (x+y)"
# exec(s,{"x":10,"y":20}) #30
# exec(s) #3
# exec(s,{"x":10},{"x":100,"y":200}) #300
# exec(s,{"x":10},{"y":200}) #210


# n = int(input("输入要计算的："))
# num = 0
# i = 1
# while i<=n:
#     num += i**i
#     i+=1

# for i in range(1,n+1):
#     num += i**i

# num = sum(map(lambda x:x**x,range(1,n+1)))
# print(num)



'''函数式编程'''
# 函数是一等公民：函数和变量、字符串、整型等属于同一地位

'''函数的可重入性'''
#调用一个函数时如果传参一定，返回值就一定
# 要求在函数中不要访问局部变量以外的其他变量 保证数据的唯一性

'''高阶函数：满足以下条件之一'''
# 形参中接收一个或多个函数
# 函数返回一个函数

# num = sum(map(lambda x,y:x**y,range(1,5),reversed(range(1,5))))#range(4,0,-1)
# print(num)


'''高阶函数'''

# filter(func,interable)
# 作用：刷选可迭代对象中数据，经过func函数运算，是True就保留，不是就丢弃

#找出100以内的奇数，偶数分别放入列表
# L1 = list(filter(lambda x:x%2==0,range(1,101)))
#
# def f(x):
#     return x%2!=0
# L2 = list(filter(f,range(1,101)))

#找100以内的素数
# def is_Prime(x):
#     for i in range(2,x):
#         if x % i == 0:
#             return False
#     return True
# L = list(filter(is_Prime,range(2,101)))
# print(L)


# L1 = [1,4,9,354,86,3,-3,-5]
# L2 = sorted(L1)#降序
# L3 = sorted(L1,reverse=True)#升序
# # L1.reverse( )#会对原列表进行改变
# L4 = sorted(L2,key=abs)#按照绝对值排序
# print(L1)
# print(L2)
# print(L3)
# print(L4)

# L = ["Tom","Jerry", "Lucy","Jack", "Rose"]
# L1 = sorted(L)
# print(L1)
# L2 = sorted(L,reverse=True)
# print(L2)
# L3 = sorted(L,key=len)#按照名字长度进行排序
# print(L3)
# L4 = sorted(L,key=lambda x:x[::-1])#将名字进行倒序
# print(L4)









'''递归函数'''
# 一定要控制层数，当符合某一个条件是，停止递归调用
# 基本上所有的递归都可以用循环解决
# 优点：把问题简单化，思路清晰，代码简洁
# 缺点：受环境影响大，当深度太大时不好控制
# import time
# def sheep ():
#     print("喜羊羊")
#     print("美羊羊")
#     print("沸羊羊")
#     print("懒羊羊")
#     time.sleep(1)
# sheep()

# def fx(n):
#     print("第",n,"层")
#     if n ==4:
#          return
#     fx(n+1)
# print(fx(1))

# def getmul(n):
#     print("第",n,"层")
#     if n == 1:
#         return 1
#     return n * getmul(n-1)
#
# print(getmul(5))




'''1,闭包'''

# 将内嵌函数的语句，以及这些语句执行所需的环境，打个包，就是闭包
# 内嵌函数条件（必须全部满足）：1，必须有一个内嵌函数2，内函数必须使用了外函数的局部变量3，外函数返回了内函数的引用
# 一般情况下，在我们认知中，调用一个函数结束了，这个函数中的所有内容都被释放了，不在内存中了
# 闭包不同，如果外部函数在结束的时候，发现了它有局部变量将来会在内嵌函数中用到，就把这个局部变量绑定给了内部函数，然后自己再结束。
# 既重用一个变量，又保证这个变量不被污染

# def myfun (y):
#     def new_func(arges):
#         return arges**y
#     return new_func
# # 创建函数（赋值的是函数对象）
# f = myfun(3)#赋值了一个函数给f ！！这里的f不是一个数值、
# # 输出函数调用结果(f()调用函数（传入参数并计算结果）)
# print(f(2))
# a= 1
# b=2
# c = 2(a+b)
